<template>
  <div>
    <el-upload
      action=""
      :auto-upload="false"
      :show-file-list="true"
      :on-change="handleFileUpload"
      accept=".xlsx,.xls"
    >
      <el-button type="primary"> 上传 Excel </el-button>
    </el-upload>

    <!-- 渲染 Excel 生成的 HTML 表格 -->
    <div v-html="tableHtml" />
  </div>
</template>

<script setup>
import { ref } from "vue";
import * as ExcelJS from "exceljs";

const tableHtml = ref(""); // 存储 HTML 表格内容
const themeColors = {
  0: "#FFFFFF", // 白色 √
  1: "#000000", // 黑色 √
  2: "#C9CDD1", // 灰色 √
  3: "#4874CB", // 蓝色 √
  4: "#D9E1F4", // 浅蓝 √
  5: "#F9CBAA", // 橙色 √
  6: "#F2BA02", // 浅橙 √
  7: "#00FF00", // 浅绿 √
  8: "#30C0B4", // 青色 √
  9: "#E54C5E", // 红色 √
  10: "#FFC7CE", // 浅红
  11: "#7030A0", // 紫色
};

// 获取单元格颜色
const getCellColor = (cell) => {
  if (cell.fill && cell.fill.fgColor) {
    if (cell.fill.fgColor.argb) {
      return `#${cell.fill.fgColor.argb.substring(2)}`; // ARGB 转 RGB
    }
    if (cell.fill.fgColor.theme !== undefined) {
      return themeColors[cell.fill.fgColor.theme] || "#FFFFFF"; // 主题色转换
    }
  }

  return ""; // 无颜色
};
// 获取单元格字体颜色
const getCellFontColor = (cell) => {
  if (cell.font && cell.font.color && cell.font.color.argb) {
    return `#${cell.font.color.argb.substring(2)}`; // ARGB 转 RGB
  }
  if (cell.font && cell.font.color && cell.font.color.theme) {
    return themeColors[cell.font.color.theme] || "#000"; // 主题色转换
  }

  return "#000"; // 默认黑色
};
const handleStyles = (cell) => {
  let styles = [];

  // 读取字体颜色
  styles.push(`color: ${getCellFontColor(cell)}`);
  // 读取背景色
  styles.push(`background-color: ${getCellColor(cell)}`);

  // 加粗
  if (cell.font && cell.font.bold) {
    styles.push("font-weight: bold");
  }

  // 文字对齐
  if (cell.alignment) {
    if (cell.alignment.horizontal) {
      styles.push(`text-align: ${cell.alignment.horizontal}`);
    }
    if (cell.alignment.vertical) {
      styles.push(`vertical-align: ${cell.alignment.vertical}`);
    }
  }

  return styles.join("; ");
};

// 处理上传的 Excel 文件
const handleFileUpload = async (file) => {
  const excelData = await readExcel(file.raw);
  tableHtml.value = excelData; // 更新 HTML 表格内容
};
// 处理常规单元格内容
const handleValueSimple = (value) => {
  if (value && typeof value === "object" && value.richText) {
    const valueStr = value.richText.reduce((acc, curr) => {
      let colorValue = "";
      if (curr.font && curr.font.color && curr.font.color.theme) {
        colorValue = getCellFontColor(curr) || `#000`;
      }
      if (curr.font && curr.font.color && curr.font.color.argb) {
        colorValue = `#${curr.font.color.argb.substring(2)}`;
      } else {
        colorValue = `#000`;
      }

      return acc + `<span style="color:${colorValue}">${curr.text}</span>`;
    }, "");

    return valueStr;
  }

  return value ? value : "";
};
// 处理合并单元格内容
const handleValue = (value) => {
  if (value && typeof value === "object" && value.richText) {
    const valueArr = value.richText.reduce((acc, curr) => {
      let colorValue = "";
      if (curr.font && curr.font.color && curr.font.color.argb) {
        colorValue = `#${curr.font.color.argb.substring(2)}`;
      } else {
        colorValue = `#000`;
      }

      const newData = curr.text
        .split(/\r/)
        .map((item) => `<p style="color:${colorValue}">${item}</p>`);
      return acc.concat(newData);
    }, []);

    return valueArr.join("").replace(/\n/g, "<br />");
  }

  return value ? value : "";
};

let worksheetIds = [];
// 读取 Excel 并转换成 HTML
const readExcel = async (file) => {
  const workbook = new ExcelJS.Workbook();
  const arrayBuffer = await file.arrayBuffer();
  const { worksheets } = await workbook.xlsx.load(arrayBuffer);
  worksheetIds = worksheets.map((v) => v.id); // 获取工作表 ID集合

  let allHtml = "";
  workbook.eachSheet(function (worksheet, sheetId) {
    // 处理合并单元格
    const merges = worksheet?.model?.merges || [];
    const currentSheetIndex = worksheetIds.indexOf(sheetId); // 获取当前工作表的索引

    allHtml +=
      '<table border="1" style="border-collapse: collapse;width:100%;margin-bottom: 20px;">';
    worksheet.eachRow((row, rowIndex) => {
      allHtml += "<tr>";

      row.eachCell((cell, colIndex) => {
        let cellValue = cell.value || "";

        // 处理合并单元格
        let rowspan = 1,
          colspan = 1;
        let isMerged = false;

        for (let merge of merges) {
          const [start, end] = merge.split(":");
          const startCell = worksheet.getCell(start);
          const endCell = worksheet.getCell(end);
          const startRow = startCell.row,
            startCol = startCell.col;
          const endRow = endCell.row,
            endCol = endCell.col;

          if (startRow === rowIndex && startCol === colIndex) {
            rowspan = endRow - startRow + 1;
            colspan = endCol - startCol + 1;
            isMerged = true;
            let styles = handleStyles(cell);
            allHtml += `<td rowspan="${rowspan}" colspan="${colspan}" style="${styles}">
              ${handleValue(startCell.value)}</td>`;
            break;
          }
          if (
            rowIndex >= startRow &&
            rowIndex <= endRow &&
            colIndex >= startCol &&
            colIndex <= endCol
          ) {
            isMerged = true;
            break;
          }
        }

        if (!isMerged) {
          let styles = handleStyles(cell);
          // 生成 HTML 单元格
          allHtml += `<td ${rowspan > 1 ? `rowspan="${rowspan}"` : ""} ${
            colspan > 1 ? `colspan="${colspan}"` : ""
          } style="${styles}">${handleValueSimple(cellValue)}</td>`;
        }
      });

      allHtml += "</tr>";
    });

    allHtml += "</table>";
  });

  return allHtml;
};
</script>